package com.thememaker.lockstyle;

import com.google.gson.Gson;
import com.thememake.common.Context;
import com.thememake.entity.ThemeFileInfo;
import com.thememake.entity.User;
import com.thememake.ui.CtsFileChooser;
import com.thememake.ui.R;
import com.thememake.ui.Toast;
import com.thememake.ui.dialog.ProgressDialog;
import com.thememake.ui.dialog.SBTFxDialog;
import com.thememake.util.FileUtils;
import com.thememaker.util.ImportScreenUtils;
import com.thememaker.util.VipControllerUtils;
import com.thememake.util.rsa.CheckLoginUtils;
import com.thememake.util.xml.XmlUtils;
import com.thememake.util.xml.bean.ModelConfig;
import com.thememake.util.xml.bean.ModelItem;
import com.thememake.util.xml.fontcolor.ReadXmlUtils;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.*;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.awt.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.List;

import static javafx.geometry.Pos.CENTER;
import static javafx.geometry.Pos.TOP_CENTER;

/**
 * Created by jiajun.jiang on 2018/1/8.
 */
public class LockscreenModelChooseDialog {
    private final HBox hBox;
    private final Button addButton;
    Stage stage;
    private ThemeFileInfo themeFileInfo;
    private ToggleGroup toggleGroup;
    private Map<String, ModelItem> nameMap = new HashMap<>();
    private Path choosePath;
    private boolean isDefult = true;
    private DirectoryChooser directoryChooser = new DirectoryChooser();
    private boolean isSuccess = true;
    private File choseFile;

    public LockscreenModelChooseDialog(final Stage stg, ThemeFileInfo themeFileInfo) {
        stage = new Stage();
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.initOwner(stg);
        stage.setTitle("选择锁屏模板");
        stage.setResizable(false);
        stage.getIcons().add(new Image(
                getClass().getResourceAsStream(Context.getDrawable(R.drawable.launcher))));
        this.themeFileInfo = themeFileInfo;

        BorderPane border = new BorderPane();
        border.getStylesheets().add("style/lockstylemain.css");
        VBox vBox = new VBox();
        vBox.getStyleClass().add("white-bg");
        vBox.setPadding(new Insets(30)); //内边距
        vBox.setAlignment(CENTER);
        vBox.setSpacing(30); //节点间距
        Button makeLockscreen = new Button("选择锁屏");
        makeLockscreen.setPadding(new Insets(0));
        makeLockscreen.setId("diy-button");
        makeLockscreen.setFont(Font.font("SimHei", FontWeight.BOLD, 18));
        makeLockscreen.setPrefSize(120, 40);
        makeLockscreen.setOnAction(event -> {
            System.err.println("makeLockscreen");
            if (choosePath != null) {
                Path lockscreenPath = Paths.get(themeFileInfo.getThemeDir().getPath(), themeFileInfo.getThemeType(), ThemeFileInfo.LOCKSTYLE_NAME, "lockscreen");
                try {
                    Files.createDirectories(lockscreenPath);
                    FileUtils.copy(choosePath.toString(), lockscreenPath.toString(), null, true, true);
                    String modelName = choosePath.getFileName().toString();
                    Path psdPath = Paths.get(choosePath.getParent().getParent().toString(), "psdmodel", modelName + ".psd");
                    System.err.println("psdPath >>> " + psdPath.toString());
                    if (Files.exists(psdPath)) {
                        if (VipControllerUtils.getInstance(themeFileInfo).canUseLockscreenPsd()) {
                            FileUtils.copyFile(psdPath, themeFileInfo.getThemeLockscreenPsdFile().toPath(), true);
                        }
                    }
                    hide();
                    saveLockstyleConfig(choosePath.getFileName().toString(), lockscreenPath.getParent());
                    new LockstyleApp(themeFileInfo).start(new Stage());
//                    new LockstyleApp(themeFileInfo).start(new Stage());
//                    new LockscreenMakeDialog(stg, themeFileInfo).show();
//                    openFile(lockscreenPath.toFile());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(stage, "请先选择锁屏模板!", 2000);
            }
        });
        addButton = new Button();
        addButton.setStyle("-fx-background-color: transparent");
        Image image = new Image(getClass().getResourceAsStream(Context.getDrawable(R.drawable.ADDLOCK)));
        ImageView imageView = new ImageView();
        imageView.setImage(image);
        addButton.setGraphic(imageView);

        hBox = new HBox();
        toggleGroup = new ToggleGroup();
        hBox.setStyle("-fx-background-color: #FFFFFF;-fx-padding: 0;-fx-focus-traversable: false");
        hBox.setPrefHeight(490);
        initLockModelChoose();

        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setStyle("-fx-background-color: #FFFFFF;-fx-padding: 0;-fx-focus-traversable: false");
        scrollPane.setContent(hBox);
        scrollPane.setPrefHeight(500);
        scrollPane.setPrefWidth(630);
        vBox.getChildren().add(scrollPane);

        HBox buttonBox = new HBox();
        buttonBox.setSpacing(30);
        buttonBox.getChildren().addAll(makeLockscreen);
        buttonBox.setAlignment(CENTER);

        vBox.getChildren().addAll(buttonBox, hBox);
        HBox hBox1 = new HBox();
        hBox1.setPadding(new Insets(8, 12, 8, 12)); //节点到边缘的距离
        hBox1.setStyle("-fx-background-color: #F7F7F7;"); //背景色
        Button importLockscreen = new Button("导入第三方锁屏（不推荐）");
        importLockscreen.setId("diy-button");
        importLockscreen.setPadding(new Insets(0));
        importLockscreen.setPrefSize(180, 25);
        importLockscreen.setFont(new Font(12));
        importLockscreen.setOnAction(event -> {

            File file = importThemeChooser();
            if (file != null) {
                ImportScreenUtils importScreenUtils = new ImportScreenUtils();
                if (importScreenUtils.checkFileChooser(file)) {
                    CheckLoginUtils.checkLogin(stage, new CheckLoginUtils.CallBack() {
                        @Override
                        public void onSuccess(User user) {
                            ProgressDialog progressDialog = new ProgressDialog(new Task<Void>() {
                                @Override
                                protected Void call() throws Exception {
                                    importScreenUtils.doImportScreen(themeFileInfo);
                                    return null;
                                }
                            }, stage, "正在导入，请稍等……");
                            progressDialog.showProgressBar(() -> {
                                if (stage != null) {
                                    Toast.makeText(stage, "导入成功，请打包主题查看", 3000);
                                    hide();
//                                    new LockscreenMakeDialog(stg, themeFileInfo).show();
                                }
                            });
                        }

                        @Override
                        public void onFail(String message) {
                        }
                    });

                } else {
                    Toast.makeText(stage, "导入锁屏格式不正确！", 3000);
                }
            }
        });
        hBox1.getChildren().addAll(importLockscreen);
        border.setTop(hBox1);

        border.setCenter(vBox);

        Scene scene = new Scene(border, 900, 700, Color.LIGHTGREEN);
        stage.setScene(scene);


        addButton.setOnAction(event -> {

            directoryChooser.setTitle("选择锁屏模板");

            FileChooser fileChooser = new FileChooser();
            fileChooser.getExtensionFilters().addAll(
                    new FileChooser.ExtensionFilter("CTS", "*.cts")
            );
            fileChooser.setTitle("选择锁屏模板");
            File file = new File(themeFileInfo.getOutModelDir(), ThemeFileInfo.LOCKSCREEN_NAME);
            if (!file.exists()) {
                if (!file.mkdirs()){
                    SBTFxDialog.showMessageDialog(stage,"导入模板时，需使用管理员权限运行","温馨提示");
                }
            }
            fileChooser.setInitialDirectory(file);
            choseFile = fileChooser.showOpenDialog(stg);
            if (choseFile != null) {
                ProgressDialog progressDialog = new ProgressDialog(new Task<Void>() {
                    @Override
                    protected Void call() throws Exception {
                        choseFile = FileUtils.unzipCTS(choseFile);
                        return null;
                    }
                }, stage, "正在校验，请稍等……");
                progressDialog.showProgressBar(() -> {
                    addLockScreenModel(choseFile, stg);
                });
//                ProgressDialog progressDialog = new ProgressDialog(new Task<Void>() {
//                    @Override
//                    protected Void call() throws Exception {
//                        if (directoryChooser.getInitialDirectory() != choseFile) {
//                            getLockscreenModel(choseFile);
//                        }
//                        return null;
//                    }
//                }, stg, "正在导入，请稍等……");
//                progressDialog.showProgressBar(() -> {
//                    if (directoryChooser.getInitialDirectory() == choseFile) {
//                        Toast.makeText(stage, "没有选择文件!", 3000);
//                    } else if (!new File(choseFile.getPath() + File.separator + "modelConfig.xml").exists()) {
//                        Toast.makeText(stage, "文件格式有误,请选择正确的文件夹!", 3000);
//                    } else {
//                        Toast.makeText(stage, "添加成功!", 3000);
//                        updateView(modelPath, previewPath);
//                    }
//                });
            }
        });
    }

    private void addLockScreenModel(File choseFile, Stage stg) {
        Path configFile = Paths.get(choseFile.getPath(), "modelConfig.xml");
        Map<String, ModelItem> addNewModel = new HashMap<>();
        if (Files.exists(configFile)) {
            Document document = ReadXmlUtils.loadXml(configFile.toString());
            Element rootElement = document.getDocumentElement();
            NodeList nodeList = rootElement.getElementsByTagName("item");
            ModelItem modelItem = new ModelItem();
            if (nodeList != null && nodeList.getLength() > 0) {
                Element element = (Element) nodeList.item(0);
                System.err.println(element.getAttribute("name") + " >>> " + element.getTextContent());
                modelItem.setName(element.getAttribute("name"));
                modelItem.setTitle(element.getAttribute("title"));
                modelItem.setDescribe(element.getAttribute("describe"));
                modelItem.setValue(element.getTextContent());
                addNewModel.put(element.getAttribute("name"), modelItem);
                Path lockDir = Paths.get(choseFile.getPath(), modelItem.getName());
                Path lockPre = Paths.get(choseFile.getPath(), modelItem.getName() + ".png");
                Path lockPsd = Paths.get(choseFile.getPath(), modelItem.getName() + ".psd");
                File toModelDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "model");
                File toPreviewDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "preview");
                File toPsdmodelDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "psdmodel");
                File toDeleteDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "model" + File.separator + modelItem.getName());
                if (directoryChooser.getInitialDirectory() == choseFile) {
                    Toast.makeText(stage, "没有选择文件!", 3000);
                } else if (!new File(choseFile.getPath() + File.separator + "modelConfig.xml").exists()) {
                    Toast.makeText(stage, "文件格式有误,请选择正确的文件夹!", 3000);
                } else if (!Files.isDirectory(lockDir) && !Files.exists(lockDir)) {
                    Toast.makeText(stage, "没有可以导入的文件夹!", 3000);
                } else {
                    if (Files.exists(toDeleteDir.toPath())) {
                        SBTFxDialog.showMessageDialog(stage, "模板已存在,是否替换?", "温馨提示", "替换", "取消", () -> {
                            isSuccess = FileUtils.deleteDir(toDeleteDir);
                            copyLockScreenFile(stg, modelItem, lockDir, lockPre, lockPsd, toModelDir, toPreviewDir, toPsdmodelDir, toDeleteDir);
                        }, () -> {
                        });
                    } else {
                        copyLockScreenFile(stg, modelItem, lockDir, lockPre, lockPsd, toModelDir, toPreviewDir, toPsdmodelDir, toDeleteDir);
                    }
                }
            }
        }
    }

    private void copyLockScreenFile(Stage stg, ModelItem modelItem, Path lockDir, Path lockPre, Path lockPsd, File toModelDir, File toPreviewDir, File toPsdmodelDir, File toDeleteDir) {
        ProgressDialog progressDialog = new ProgressDialog(new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                FileUtils.copyDir(lockDir.toString(), toDeleteDir.getPath(), true);
                if (Files.exists(lockPre)) {
                    FileUtils.copyFile(lockPre.toString(), toPreviewDir + File.separator + lockPre.getFileName(), true);
                }
                if (Files.exists(lockPsd)) {
                    FileUtils.copyFile(lockPsd.toString(), toPsdmodelDir + File.separator + lockPsd.getFileName(), true);
                }
                try {
                    nameMap.put(modelItem.getName(), modelItem);
                    ModelConfig modelConfig = new ModelConfig();
                    List<ModelItem> item = new ArrayList<>();
                    Iterator it = nameMap.entrySet().iterator();
                    while (it.hasNext()) {
                        Map.Entry entry = (Map.Entry) it.next();
                        item.add((ModelItem) entry.getValue());
                    }
                    modelConfig.setModelItems(item);
                    XmlUtils.java2xml(modelConfig, ModelConfig.class, toModelDir + File.separator + "modelConfig.xml");
                } catch (Exception e) {
                    e.printStackTrace();
                    isSuccess = false;
                }
                return null;
            }
        }, stg, "正在导入，请稍等……");
        progressDialog.showProgressBar(() -> {
            if (!isSuccess){
                SBTFxDialog.showMessageDialog(stage,"导入模板时，需使用管理员权限运行","温馨提示");
            }else {
                updateView(modelPath, previewPath);
            }
        });

    }

    private void getLockscreenModel(File initialDirectory) {
        Path configFile = Paths.get(initialDirectory.getPath(), "modelConfig.xml");
        Map<String, ModelItem> addNewModel = new HashMap<>();
        if (Files.exists(configFile)) {
            Document document = ReadXmlUtils.loadXml(configFile.toString());
            Element rootElement = document.getDocumentElement();
            NodeList nodeList = rootElement.getElementsByTagName("item");
            ModelItem modelItem = new ModelItem();
            if (nodeList != null && nodeList.getLength() > 0) {
                Element element = (Element) nodeList.item(0);
                System.err.println(element.getAttribute("name") + " >>> " + element.getTextContent());
                modelItem.setName(element.getAttribute("name"));
                modelItem.setTitle(element.getAttribute("title"));
                modelItem.setDescribe(element.getAttribute("describe"));
                modelItem.setValue(element.getTextContent());
                addNewModel.put(element.getAttribute("name"), modelItem);
            }

            Path lockDir = Paths.get(initialDirectory.getPath(), modelItem.getName());
            Path lockPre = Paths.get(initialDirectory.getPath(), modelItem.getName() + ".png");
            Path lockPsd = Paths.get(initialDirectory.getPath(), modelItem.getName() + ".psd");
            File toModelDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "model");
            File toPreviewDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "preview");
            File toPsdmodelDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "psdmodel");
            File toDeleteDir = FileUtils.getResFileOfThemeModel("vivo", "lockscreen" + File.separator + "model" + File.separator + modelItem.getName());
            if (Files.isDirectory(lockDir) && Files.exists(lockDir)) {
                if (Files.exists(toDeleteDir.toPath())) {
                    FileUtils.deleteDir(toDeleteDir);
                }
                try {

                    FileUtils.copyDir(lockDir.toString(), toDeleteDir.getPath(), true);
                } catch (IOException e) {
                    isSuccess = false;
                    e.printStackTrace();
                }
            }
            if (Files.exists(lockPre)) {
                FileUtils.copyFile(lockPre.toString(), toPreviewDir + File.separator + lockPre.getFileName(), true);
            }
            if (Files.exists(lockPsd)) {
                FileUtils.copyFile(lockPsd.toString(), toPsdmodelDir + File.separator + lockPsd.getFileName(), true);
            }

            try {
                nameMap.put(modelItem.getName(), modelItem);
                ModelConfig modelConfig = new ModelConfig();
                List<ModelItem> item = new ArrayList<>();
                Iterator it = nameMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry entry = (Map.Entry) it.next();
                    item.add((ModelItem) entry.getValue());
                }
                modelConfig.setModelItems(item);
                XmlUtils.java2xml(modelConfig, ModelConfig.class, toModelDir + File.separator + "modelConfig.xml");
            } catch (Exception e) {
                isSuccess = false;
                e.printStackTrace();
            }
        }
    }

    private void saveLockstyleConfig(String name, Path lockstylePath) {
        Path lockstyleConfigPath = Paths.get(lockstylePath.toString(), "lockstyleConfig.json");
        BufferedWriter writer = null;
        try {
            if (Files.exists(lockstyleConfigPath)) {
                Files.delete(lockstyleConfigPath);
            }
            Files.createFile(lockstyleConfigPath);
            writer = Files.newBufferedWriter(lockstyleConfigPath);
            writer.write(new Gson().toJson(nameMap.get(name)));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private File importThemeChooser() {
        File file = null;
        switch (themeFileInfo.getThemeType()) {
            default:
                file = CtsFileChooser.getInstance().showOpenDirDialog(stage, "打开锁屏文件夹");
                break;
        }
        return file;
    }

    private Path modelPath;
    private Path previewPath;

    private void initLockModelChoose() {
        choosePath = null;
        File lockScreenFile = FileUtils.getResFileOfThemeModel(themeFileInfo.getThemeType(), "lockscreen");
        modelPath = Paths.get(lockScreenFile.getPath(), "model");
        previewPath = Paths.get(lockScreenFile.getPath(), "preview");
        Path xmlPath = Paths.get(modelPath.toString(), "modelConfig.xml");
        if (Files.exists(xmlPath)) {
            System.err.println(Files.exists(xmlPath));
            Document document = ReadXmlUtils.loadXml(xmlPath.toString());
            Element rootElement = document.getDocumentElement();
            NodeList nodeList = rootElement.getElementsByTagName("item");
            if (nodeList != null && nodeList.getLength() > 0) {
                for (int i = 0; i < nodeList.getLength(); i++) {
                    Element element = (Element) nodeList.item(i);
                    System.err.println(element.getAttribute("name") + " >>> " + element.getTextContent());
                    ModelItem modelItem = new ModelItem();
                    modelItem.setName(element.getAttribute("name"));
                    modelItem.setTitle(element.getAttribute("title"));
                    modelItem.setDescribe(element.getAttribute("describe"));
                    modelItem.setValue(element.getTextContent());
                    nameMap.put(element.getAttribute("name"), modelItem);
                }
            }
        }
        updateView(modelPath, previewPath);

        toggleGroup.selectedToggleProperty().addListener(
                (ObservableValue<? extends Toggle> ov, Toggle old_toggle,
                 Toggle new_toggle) -> {
                    if (toggleGroup.getSelectedToggle() != null) {
                        choosePath = Paths.get(modelPath.toString(), toggleGroup.getSelectedToggle().getUserData().toString());
                        System.err.println("getUserData >>> " + toggleGroup.getSelectedToggle().getUserData().toString());
                    }
                });
    }

    private void updateView(Path modelPath, Path previewPath) {
        hBox.getChildren().remove(0, hBox.getChildren().size());
        try {
            FileUtils.traverseSubfolders(modelPath).forEach(path -> {
                hBox.getChildren().add(InitItem(modelPath, path.getFileName().toString(), Paths.get(previewPath.toString(), path.getFileName().toString() + ".png").toString()));
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        hBox.getChildren().addAll(addButton);
    }

    private VBox InitItem(Path modelPath, String name, String picPath) {
//        scrollHbox.setStyle("-fx-background-color:red");
        VBox vBox = new VBox();
        vBox.setPrefSize(300, 400);
        vBox.setSpacing(20);
        vBox.setAlignment(TOP_CENTER);
        ImageView imageView = new ImageView();
        Image image = new Image(Paths.get(picPath).toUri().toString());
        imageView.setImage(image);
        imageView.setFitWidth(200);
        imageView.setFitHeight(355);
        RadioButton rb1 = new RadioButton();
        rb1.setId("diy-fontColor");
        rb1.setFont(new Font(14));
        if (nameMap != null && nameMap.get(name) != null) {
            rb1.setText(nameMap.get(name).getValue());
        } else {
            rb1.setText(name);
        }
        rb1.setContentDisplay(ContentDisplay.TOP);
        rb1.setLineSpacing(20);
        rb1.setAlignment(Pos.CENTER);
        rb1.setUserData(name);
        rb1.setToggleGroup(toggleGroup);
        if (isDefult) {
            rb1.setSelected(true);
            choosePath = Paths.get(modelPath.toString(), name);
            isDefult = false;
        }
        Text text = new Text();
        text.setWrappingWidth(200);
        text.setStyle("-fx-fill: #C2C0CD");
        if (nameMap.get(name) != null) {
            if (nameMap.get(name).getTitle() != null) {
                text.setText("锁屏简介：" + nameMap.get(name).getTitle().replace("\\n", "\n"));
            } else {
                text.setText("锁屏简介：");
            }
        } else {
            text.setText("锁屏简介：");
        }


        imageView.setOnMouseClicked(event -> {
            rb1.setSelected(true);
        });

        vBox.getChildren().addAll(imageView, rb1, text);

        return vBox;

//        return vBox;
    }

    public LockscreenModelChooseDialog show() {
        stage.show();
        return this;
    }

    public LockscreenModelChooseDialog hide() {
        stage.hide();
        return this;
    }


    public Stage getStage() {
        return stage;
    }


    public void openFile(File file) {
        EventQueue.invokeLater(() -> {
            try {
                Desktop.getDesktop().open(file);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }


}
